#include "colorthemedialog.h"
#include "globalvar.h"

ColorThemeDialog::ColorThemeDialog(QWidget *parent): QDialog(parent)
{
    this->setFixedSize(860, 600);
    this->setWindowTitle(tr("Color Theme Customize"));
    this->setWindowIcon(QPixmap(":images/colorThemeOption.png"));

    QVBoxLayout *mainFormLayout = new QVBoxLayout; //定义垂直布局器
    this->setLayout(mainFormLayout);//将mainFormLayout设定为本窗口的布局器

    mainFormLayout->setContentsMargins(10, 10, 10, 10);
    mainFormLayout->setSpacing(10);

    themeLabel=new QLabel;

    codeEditor = new CodeEditor;

    keywordButton = new QPushButton(tr("Keyword"));
    functionButton = new QPushButton(tr("Function"));
    numberButton = new QPushButton(tr("Number"));
    qtClassButton = new QPushButton(tr("Qt Class"));
    preprocessButton = new QPushButton(tr("Preprocessor"));
    commentButton = new QPushButton(tr("Comment"));
    stringButton = new QPushButton(tr("String"));
    symbolButton = new QPushButton(tr("Symbol"));
    foregroundButton = new QPushButton(tr("Others"));

    okButton = new QPushButton(tr("OK")); //定义OK按钮
    defaultButton = new QPushButton(tr("Default")); //定义Default按钮
    cancelButton = new QPushButton(tr("Cancel")); //定义Cancel按钮

    QWidget *widget1=new QWidget;
    QHBoxLayout *hLayout1 = new QHBoxLayout(widget1); //定义水平布局器
    hLayout1->setContentsMargins(0, 0, 0, 0);
    hLayout1->setSpacing(10);

    QVBoxLayout *vLayout1 = new QVBoxLayout; //定义水平布局器
    vLayout1->setContentsMargins(0, 0, 0, 0);
    vLayout1->setSpacing(15);

    codeEditor->setReadOnly(true);
    QFont editorFont=codeEditor->font();
    editorFont.setPointSize(13);
    codeEditor->setFont(editorFont);

    if (GlobalVar::colorTheme==0) themeLabel->setText(tr("Light Theme"));
    else if (GlobalVar::colorTheme==1) themeLabel->setText(tr("Gray Theme"));
    else themeLabel->setText(tr("Dark Theme"));

    themeLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed);
    themeLabel->setAlignment(Qt::AlignCenter);

    themeLabel->setFont(QFont(QStringList({"Arial","Microsoft Yahei"}),16, QFont::Bold));
    preprocessButton->setFont(editorFont);
    keywordButton->setFont(editorFont);
    functionButton->setFont(editorFont);
    numberButton->setFont(editorFont);
    qtClassButton->setFont(editorFont);
    commentButton->setFont(editorFont);
    stringButton->setFont(editorFont);
    symbolButton->setFont(editorFont);
    foregroundButton->setFont(editorFont);

    vLayout1->addWidget(themeLabel);
    vLayout1->addWidget(preprocessButton);
    vLayout1->addWidget(keywordButton);
    vLayout1->addWidget(functionButton);
    vLayout1->addWidget(numberButton);
    vLayout1->addWidget(qtClassButton);
    vLayout1->addWidget(commentButton);
    vLayout1->addWidget(stringButton);
    vLayout1->addWidget(symbolButton);
    vLayout1->addWidget(foregroundButton);
    vLayout1->addStretch();

    connect(keywordButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(functionButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(numberButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(qtClassButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(preprocessButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(commentButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(stringButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(symbolButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);
    connect(foregroundButton, &QPushButton::clicked, this, &ColorThemeDialog::buttonClicked);

    int tabSpaceNumber = 4; //读取Tab符宽度并设置
    QFontMetrics fm(editorFont);
    double fontWidth = fm.horizontalAdvance("a");
    codeEditor->setTabStopDistance(fontWidth * tabSpaceNumber);
    codeEditor->setPlainText("#include <QtWidgets/QtWidgets>//包含QtWidgets头文件\n"
            "#define cn QString::fromLocal8Bit\n\n"
            "class MainWindow : public QMainWindow\n"
            "{\n"
            "	public:\n"
            "	    MainWindow(QWidget *parent = nullptr);//构造函数\n"
            "};\n"
            "\n"
            "MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)\n"
            "{\n"
            "	this->setWindowTitle(\"MainWindow\");//设定主窗口标题\n"
            "	this->resize(800,480);//改变窗口尺寸\n"
            "}\n\n"
            "int main(int argc, char *argv[])\n"
            "{\n"
            "	QApplication app(argc, argv);//建立程序app\n"
            "	app.setFont(QFont(QStringList{\"Arial\",\"微软雅黑\"},11));//设定程序字体\n"
            "	\n"
            "	MainWindow mainWindow;//定义一个名为mainWindow的窗口对象\n"
            "	mainWindow.show();//显示mainWindow窗口\n"
            "	\n"
            "	app.exec();//开启app程序的消息循环\n"
            "}");

    hLayout1->addLayout(vLayout1);
    hLayout1->addWidget(codeEditor);

    QHBoxLayout *hLayout2 = new QHBoxLayout; //定义水平布局器
    hLayout2->setContentsMargins(0, 0, 0, 0);
    hLayout2->setSpacing(10);
    hLayout2->addStretch();
    hLayout2->addWidget(okButton);
    hLayout2->addWidget(defaultButton);
    hLayout2->addWidget(cancelButton);
    hLayout2->addStretch();

    mainFormLayout->addWidget(widget1);
    mainFormLayout->addLayout(hLayout2);

    connect(okButton, &QPushButton::clicked, this, &ColorThemeDialog::okButtonClicked);//OK按钮点击和处理函数的连接
    connect(defaultButton, &QPushButton::clicked, this, &ColorThemeDialog::defaultButtonClicked);//Default按钮点击和处理函数的连接
    connect(cancelButton, &QPushButton::clicked, this, &ColorThemeDialog::cancelButtonClicked);//Cancel按钮点击和处理函数的连接

    changeButtonsTextColor();
}

void ColorThemeDialog::buttonClicked()
{
    QPushButton *clickedButton=dynamic_cast<QPushButton*>(sender());
    QColor color = QColorDialog::getColor(clickedButton->palette().color(QPalette::ButtonText), this,"Color Selection");
    if(color.isValid())
    {
        if (clickedButton==stringButton&&color==GlobalVar::symbolColor[GlobalVar::colorTheme])
        {
            QMessageBox::warning(this, "Warning", "String color should be different from symbol color!");
            return;
        }

        if (clickedButton==symbolButton&&color==GlobalVar::stringColor[GlobalVar::colorTheme])
        {
            QMessageBox::warning(this, "Warning", "Symbol color should be different from string color!");
            return;
        }

        QColor backColor=GlobalVar::editorBackground[GlobalVar::colorTheme];

        int redDiff=qAbs(color.red()-backColor.red())/1.5;
        int greenDiff=qAbs(color.green()-backColor.green());
        int blueDiff=qAbs(color.blue()-backColor.blue())/2.0;
        int maxRgbDiff=std::max({redDiff, greenDiff, blueDiff});
        if (maxRgbDiff<60)
        {
            QMessageBox::warning(this, "Warning", tr("The selected color is close to background!")+"\n"+tr("Please select a color with enough contrast."));
            return;
        }

        if (clickedButton==keywordButton) GlobalVar::keywordColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==functionButton) GlobalVar::functionColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==numberButton) GlobalVar::numberColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==qtClassButton) GlobalVar::qtClassColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==preprocessButton) GlobalVar::preprocessColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==commentButton) GlobalVar::commentColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==stringButton) GlobalVar::stringColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==symbolButton) GlobalVar::symbolColor[GlobalVar::colorTheme] =color;
        else if (clickedButton==foregroundButton) GlobalVar::editorForeground[GlobalVar::colorTheme] =color;

        clickedButton->setStyleSheet(QString("color: %1;background-color: %2").arg(color.name(),backColor.name()));
        codeEditor->changeColorTheme();
    }
}

void ColorThemeDialog::changeButtonsTextColor()
{
    QColor backColor=GlobalVar::editorBackground[GlobalVar::colorTheme];

    keywordButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::keywordColor[GlobalVar::colorTheme].name())
                                +QString("background-color: %1;").arg(backColor.name()));
    functionButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::functionColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    numberButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::numberColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    qtClassButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::qtClassColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    preprocessButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::preprocessColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    commentButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::commentColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    stringButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::stringColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    symbolButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::symbolColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    foregroundButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::editorForeground[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
}

void ColorThemeDialog::showEvent(QShowEvent* event)
{
    backKeywordColor=GlobalVar::keywordColor;
    backFunctionColor=GlobalVar::functionColor;
    backNumberColor=GlobalVar::numberColor;
    backQtClassColor=GlobalVar::qtClassColor;
    backPreprocessColor=GlobalVar::preprocessColor;
    backCommentColor=GlobalVar::commentColor;
    backStringColor=GlobalVar::stringColor;
    backSymbolColor=GlobalVar::symbolColor;
    backEditorForeground=GlobalVar::editorForeground;

    if (codeEditor->horizontalScrollBar()->isVisible())
        this->setFixedWidth(this->width()+codeEditor->horizontalScrollBar()->maximum());

    if (codeEditor->verticalScrollBar()->isVisible())
        this->setFixedHeight(this->height()+codeEditor->verticalScrollBar()->maximum()*codeEditor->fontMetrics().lineSpacing());
}

void ColorThemeDialog::okButtonClicked()
{
    this->accept();//OK按钮点击以后发出Accepted返回值
}

void ColorThemeDialog::defaultButtonClicked()
{
    QColor backColor=GlobalVar::editorBackground[GlobalVar::colorTheme];

    keywordButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultKeywordColor[GlobalVar::colorTheme].name())
                                +QString("background-color: %1;").arg(backColor.name()));
    functionButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultFunctionColor[GlobalVar::colorTheme].name())
                                 +QString("background-color: %1;").arg(backColor.name()));
    numberButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultNumberColor[GlobalVar::colorTheme].name())
                               +QString("background-color: %1;").arg(backColor.name()));
    qtClassButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultQtClassColor[GlobalVar::colorTheme].name())
                                +QString("background-color: %1;").arg(backColor.name()));
    preprocessButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultPreprocessColor[GlobalVar::colorTheme].name())
                                   +QString("background-color: %1;").arg(backColor.name()));
    commentButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultCommentColor[GlobalVar::colorTheme].name())
                                +QString("background-color: %1;").arg(backColor.name()));
    stringButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultStringColor[GlobalVar::colorTheme].name())
                               +QString("background-color: %1;").arg(backColor.name()));
    symbolButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultSymbolColor[GlobalVar::colorTheme].name())
                               +QString("background-color: %1;").arg(backColor.name()));
    foregroundButton->setStyleSheet(QString("color: %1;").arg(GlobalVar::defaultEditorForeground[GlobalVar::colorTheme].name())
                                   +QString("background-color: %1;").arg(backColor.name()));

    GlobalVar::keywordColor =GlobalVar::defaultKeywordColor;
    GlobalVar::functionColor=GlobalVar::defaultFunctionColor;
    GlobalVar::numberColor =GlobalVar::defaultNumberColor;
    GlobalVar::symbolColor =GlobalVar::defaultSymbolColor;
    GlobalVar::qtClassColor =GlobalVar::defaultQtClassColor;
    GlobalVar::preprocessColor =GlobalVar::defaultPreprocessColor;
    GlobalVar::commentColor =GlobalVar::defaultCommentColor;
    GlobalVar::stringColor =GlobalVar::defaultStringColor;
    GlobalVar::editorForeground =GlobalVar::defaultEditorForeground;

    codeEditor->changeColorTheme();
}

void ColorThemeDialog::cancelButtonClicked()
{
    GlobalVar::keywordColor=backKeywordColor;
    GlobalVar::functionColor=backFunctionColor;
    GlobalVar::numberColor=backNumberColor;
    GlobalVar::qtClassColor=backQtClassColor;
    GlobalVar::preprocessColor=backPreprocessColor;
    GlobalVar::commentColor=backCommentColor;
    GlobalVar::stringColor=backStringColor;
    GlobalVar::symbolColor=backSymbolColor;
    GlobalVar::editorForeground=backEditorForeground;

    this->reject();//Cancel按钮点击以后发出Rejected返回值
}
